package com.scanner.scannersdk;


import android.app.Activity;
import android.app.Application;
import android.app.FragmentManager;
import android.bluetooth.BluetoothAdapter;
import android.bluetooth.BluetoothDevice;
import android.content.BroadcastReceiver;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.content.ServiceConnection;
import android.os.Bundle;
import android.os.Handler;
import android.os.IBinder;
import android.os.Message;
import android.util.Log;
import android.widget.Toast;


import com.scanner.scannersdk.callback.DicoverBuetoothCallback;
import com.scanner.scannersdk.callback.LifeListener;
import com.scanner.scannersdk.callback.SdkMessage;

import org.greenrobot.eventbus.EventBus;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Set;

import static android.content.ContentValues.TAG;

public class MainScannerSdk implements MainScannerInterface {

    public String Scanner_type = "c";

    private static Application main_context;
    static MainScannerSdk mainScannerSdk;
    private int model = 0;
    private List<BluetoothDevice> bluetoothDeviceList = new ArrayList<>();
    private ServiceConnection usbConnection;
    BluetoothAdapter mBtAdapter;
    BroadcastReceiver mReceiver;
    Boolean connected = false;
    public String name = "";
    private static String MODEL_STYLE;

    /*
     *initsdk
     * */
    public static void initSdk(Application application) {
        main_context = application;
        setFilters();
    }

    public static MainScannerSdk getInstence() {
        if (mainScannerSdk == null) {
            mainScannerSdk = new MainScannerSdk();
        }
        return mainScannerSdk;
    }

    private MainScannerSdk() {
        mBtAdapter = BluetoothAdapter.getDefaultAdapter();

    }

    //连接蓝牙
    public Boolean conectSppBlueTooth(BluetoothDevice device) {
        Intent intent_servce;
        name = device.getName();
        boolean connect = false;
        switch (mainScannerSdk.getModel()) {
            case SdkValue.MODE_BLURTOOTHBLE:
                if (device.getType() == BluetoothDevice.DEVICE_TYPE_LE||device.getType()==BluetoothDevice.DEVICE_TYPE_DUAL) {
                    connected = true;
                    intent_servce = new Intent(main_context, BleBlueToothServce.class);
                    intent_servce.putExtra("bluetoothDevice", device);
                    main_context.startService(intent_servce);
                    connect = true;
                } else {
                    Toast.makeText(main_context, "This device is not a BLE Bluetooth", Toast.LENGTH_SHORT).show();
                    EventBus.getDefault().post(SdkMessage.getInstance(null, SdkValue.connectbt_fail, null));
                }
                break;
            case SdkValue.MODE_BLURTOOTHSPP:
                if (device.getType() == BluetoothDevice.DEVICE_TYPE_CLASSIC||device.getType()==BluetoothDevice.DEVICE_TYPE_DUAL) {
                    connected = true;
                    intent_servce = new Intent(main_context, SppBlueToothServce.class);
                    intent_servce.putExtra("bluetoothDevice", device);
                    main_context.startService(intent_servce);
                    connect = true;
                } else {
                    Toast.makeText(main_context, "This device is not a SPP Bluetooth", Toast.LENGTH_SHORT).show();
                    EventBus.getDefault().post(SdkMessage.getInstance(null, SdkValue.connectbt_fail, null));
                }
                break;
        }
        return connect;
    }

    /*
     * Notifications from UsbService will be received here.
     * usb_cdc Notifications
     */
    private static final BroadcastReceiver mUsbReceiver = new BroadcastReceiver() {
        @Override
        public void onReceive(Context context, Intent intent) {
            switch (intent.getAction()) {
                case UsbService.ACTION_USB_PERMISSION_GRANTED: // USB PERMISSION GRANTED
//                    Toast.makeText(context, "USB Ready", Toast.LENGTH_SHORT).show();
                    EventBus.getDefault().postSticky(SdkMessage.getInstanceInt("", SdkValue.SdkMessageType_ConnectUsb, null));
                    break;
                case UsbService.ACTION_USB_PERMISSION_NOT_GRANTED: // USB PERMISSION NOT GRANTED
                    Toast.makeText(context, "USB Permission not granted", Toast.LENGTH_SHORT).show();
                    break;
                case UsbService.ACTION_NO_USB: // NO USB CONNECTED
                    Toast.makeText(context, "No USB connected", Toast.LENGTH_SHORT).show();
                    break;
                case UsbService.ACTION_USB_DISCONNECTED: // USB DISCONNECTED
                    Toast.makeText(context, "USB disconnected", Toast.LENGTH_SHORT).show();
                    break;
                case UsbService.ACTION_USB_NOT_SUPPORTED: // USB NOT SUPPORTED
                    Toast.makeText(context, "USB device not supported", Toast.LENGTH_SHORT).show();
                    break;
            }
        }
    };

    private UsbService usbService;
    private MyHandler mHandler;

    /*
     * 蓝牙spp获取蓝牙列表
     * */
    public void getBlueToothList(final DicoverBuetoothCallback dicoverBuetoothCallback, Activity activity) {
        Log.d("bluelist","---------------");
        if (mainScannerSdk != null) {
            if (model == SdkValue.MODE_BLURTOOTHSPP || model == SdkValue.MODE_BLURTOOTHHID || model == SdkValue.MODE_BLURTOOTHBLE) {
                if (mBtAdapter.isDiscovering()) {
                    mBtAdapter.cancelDiscovery();
                }
                // 新建一个 BroadcastReceiver来接收ACTION_FOUND广播
                mReceiver = new BroadcastReceiver() {
                    public void onReceive(Context context, Intent intent) {
                        String action = intent.getAction();
                        Boolean include = true;
                        // 发现设备
                        if (BluetoothDevice.ACTION_FOUND.equals(action)) {
                            //获得 BluetoothDevice
                            BluetoothDevice device = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);
                            for (int i = 0; i < bluetoothDeviceList.size(); i++) {
                                //不显示name为空的蓝牙
                                if (device.getName() != null) {
                                    if (bluetoothDeviceList.get(i).getName().equals(device.getName())) {
                                        include = true;
                                        return;
                                    } else {
                                        include = false;
                                    }
                                }
                            }
                            if (include == false || (bluetoothDeviceList.size() == 0 && device.getName() != null)) {
                                bluetoothDeviceList.add(device);
                                dicoverBuetoothCallback.findCallback(bluetoothDeviceList);
                            }
                        }
                    }
                };
                //设置IntentFilter
                IntentFilter filter = new IntentFilter(BluetoothDevice.ACTION_FOUND);
                main_context.registerReceiver(mReceiver, filter);
                mBtAdapter.startDiscovery();
            } else {
                Toast.makeText(main_context, "请选择正确的连接模式", Toast.LENGTH_SHORT).show();
            }
        } else {
            Toast.makeText(main_context, "SDK未初始化", Toast.LENGTH_SHORT).show();
        }
        //添加生命监听
        addLifeListener(activity);
    }

    public int getModel() {
        return model;
    }


    /*
     * 设置模式
     * */
    public void setModel(int model) {

        switch (model) {
            case SdkValue.MODE_BLURTOOTHBLE:
                stopService(model);
                this.model = model;
                break;
            case SdkValue.MODE_BLURTOOTHSPP:
                stopService(model);
                this.model = model;
                break;
            case SdkValue.MODE_BLURTOOTHHID:
                stopService(model);
                this.model = model;
                break;
            case SdkValue.MODE_USBHID:
                stopService(model);
                this.model = model;
                break;
            case SdkValue.MODE_USBVCOMM:
                //去连接串口
                stopService(model);
                this.model = model;
                mHandler = new MyHandler();
                usbConnection = new ServiceConnection() {
                    @Override
                    public void onServiceConnected(ComponentName arg0, IBinder arg1) {
                        usbService = ((UsbService.UsbBinder) arg1).getService();
                        usbService.setHandler(mHandler);
                    }

                    @Override
                    public void onServiceDisconnected(ComponentName arg0) {
                        usbService = null;
                    }
                };
                startService(UsbService.class, usbConnection, null); // Start UsbService(if it was not started before) and Bind it
                break;
        }
    }


    private void startService(Class<?> service, ServiceConnection serviceConnection, Bundle extras) {
        if (!UsbService.SERVICE_CONNECTED) {
            Intent startService = new Intent(main_context, service);
            if (extras != null && !extras.isEmpty()) {
                Set<String> keys = extras.keySet();
                for (String key : keys) {
                    String extra = extras.getString(key);
                    startService.putExtra(key, extra);
                }
            }
            main_context.startService(startService);
        }
        Intent bindingIntent = new Intent(main_context, service);
        main_context.bindService(bindingIntent, serviceConnection, Context.BIND_AUTO_CREATE);
    }

    //暂停现有连接服务
    private void stopService(int model) {
        switch (this.model) {
            case SdkValue.MODE_BLURTOOTHBLE:
                switch (model) {
                    case SdkValue.MODE_BLURTOOTHBLE:
                        EventBus.getDefault().postSticky(SdkMessage.getInstance(SdkValue.TRANSPORT_BTBLE, SdkValue.SdkMessageType_Send, null));
                        break;
                    case SdkValue.MODE_BLURTOOTHHID:
                        EventBus.getDefault().postSticky(SdkMessage.getInstance(SdkValue.TRANSPORT_BTHID, SdkValue.SdkMessageType_Send, null));
                        break;
                    case SdkValue.MODE_USBHID:
                        EventBus.getDefault().postSticky(SdkMessage.getInstance(SdkValue.TRANSPORT_USBHID, SdkValue.SdkMessageType_Send, null));
                        break;
                    case SdkValue.MODE_USBVCOMM:
                        EventBus.getDefault().postSticky(SdkMessage.getInstance(SdkValue.TRANSPORT_USBSPP, SdkValue.SdkMessageType_Send, null));
                        break;
                }
                EventBus.getDefault().postSticky(SdkMessage.getInstance("", SdkValue.getSdkMessageType_DisBleBluetoothAndServce, null));
                break;

            case SdkValue.MODE_BLURTOOTHSPP:
                switch (model) {
                    case SdkValue.MODE_BLURTOOTHBLE:
                        EventBus.getDefault().postSticky(SdkMessage.getInstance(SdkValue.TRANSPORT_BTBLE, SdkValue.SdkMessageType_Send, null));
                        break;
                    case SdkValue.MODE_BLURTOOTHHID:
                        EventBus.getDefault().postSticky(SdkMessage.getInstance(SdkValue.TRANSPORT_BTHID, SdkValue.SdkMessageType_Send, null));
                        break;
                    case SdkValue.MODE_USBHID:
                        EventBus.getDefault().postSticky(SdkMessage.getInstance(SdkValue.TRANSPORT_USBHID, SdkValue.SdkMessageType_Send, null));
                        break;
                    case SdkValue.MODE_USBVCOMM:
                        EventBus.getDefault().postSticky(SdkMessage.getInstance(SdkValue.TRANSPORT_USBSPP, SdkValue.SdkMessageType_Send, null));
                        break;
                }
                EventBus.getDefault().postSticky(SdkMessage.getInstance("", SdkValue.getSdkMessageType_DisSppBluetoothAndServce, null));
                break;
            case SdkValue.MODE_BLURTOOTHHID:

                break;
            case SdkValue.MODE_USBHID:

                break;
            case SdkValue.MODE_USBVCOMM:
//                main_context.unregisterReceiver(mUsbReceiver);
                switch (model) {
                    case SdkValue.MODE_BLURTOOTHBLE:
                        EventBus.getDefault().postSticky(SdkMessage.getInstance(SdkValue.TRANSPORT_BTBLE, SdkValue.SdkMessageType_Send, null));
                        break;
                    case SdkValue.MODE_BLURTOOTHHID:
                        EventBus.getDefault().postSticky(SdkMessage.getInstance(SdkValue.TRANSPORT_BTHID, SdkValue.SdkMessageType_Send, null));
                        break;
                    case SdkValue.MODE_USBHID:
                        EventBus.getDefault().postSticky(SdkMessage.getInstance(SdkValue.TRANSPORT_USBHID, SdkValue.SdkMessageType_Send, null));
                        break;
                    case SdkValue.MODE_USBVCOMM:
                        EventBus.getDefault().postSticky(SdkMessage.getInstance(SdkValue.TRANSPORT_USBSPP, SdkValue.SdkMessageType_Send, null));
                        break;
                }
                Intent intent_usb = new Intent(main_context, UsbService.class);
                main_context.stopService(intent_usb);
                main_context.unbindService(usbConnection);
                break;
        }
    }

    private void addLifeListener(Activity activity) {
        LifeListenerFragment fragment = getLifeListenerFragment(activity);
        fragment.addLifeListener(mLifeListener);
    }

    private LifeListenerFragment getLifeListenerFragment(Activity activity) {
        FragmentManager manager = activity.getFragmentManager();
        return getLifeListenerFragment(manager);
    }

    //添加空白fragment
    private LifeListenerFragment getLifeListenerFragment(FragmentManager manager) {
        LifeListenerFragment fragment = (LifeListenerFragment) manager.findFragmentByTag("s");
        if (fragment == null) {
            fragment = new LifeListenerFragment();
            manager.beginTransaction().add(fragment, "ds").commitAllowingStateLoss();
        }
        return fragment;
    }

    private LifeListener mLifeListener = new LifeListener() {
        @Override
        public void onCreate(Bundle bundle) {
            Log.d(TAG, "onCreate");
        }

        @Override
        public void onStart() {
            Log.d(TAG, "onStart");
        }

        @Override
        public void onResume() {
            Log.d(TAG, "onResume");
        }

        @Override
        public void onPause() {
            Log.d(TAG, "onPause");
        }

        @Override
        public void onStop() {

        }

        @Override
        public void onDestroy() {
            Log.d(TAG, "onDestroy");
            bluetoothDeviceList.clear();
            mBtAdapter.cancelDiscovery();
            main_context.unregisterReceiver(mReceiver);
        }
    };


    private static void setFilters() {
        IntentFilter filter = new IntentFilter();
        filter.addAction(UsbService.ACTION_USB_PERMISSION_GRANTED);
        filter.addAction(UsbService.ACTION_NO_USB);
        filter.addAction(UsbService.ACTION_USB_DISCONNECTED);
        filter.addAction(UsbService.ACTION_USB_NOT_SUPPORTED);
        filter.addAction(UsbService.ACTION_USB_PERMISSION_NOT_GRANTED);
        main_context.registerReceiver(mUsbReceiver, filter);
    }

//    //接受到消息，如果是
//    @Subscribe(threadMode = ThreadMode.MAIN)
//    public void eventBbus(NetumSdkMessage netumSdkMessage) {
//        if (netumSdkMessage.s != null) {
//            String msg = new String(netumSdkMessage.s);
//            switch (netumSdkMessage.type) {
//                case SdkValue.SdkMessageType_Receve:
//                    setCompilerModel(msg);
//                    break;
//            }
//        }
//    }


    //设置二维模组型号
    public static void setCompilerModel(String msg) {
        Log.d("tag", "" + msg);
        if (msg.contains("SE4750")) {
            MODEL_STYLE = SdkValue.MODELSTYLE_SE4750;
            Log.d("tag", "" + MODEL_STYLE);
        } else if (msg.contains("NT-C06H")) {
            MODEL_STYLE = SdkValue.MODELSTYLE_NT_C06H;
        } else if (msg.contains("EX25")) {
            MODEL_STYLE = SdkValue.MODELSTYLE_EX25;
        } else if (msg.contains("NT280H")) {
            MODEL_STYLE = SdkValue.MODELSTYLE_NT_280H;
            Log.d("tag", "tag:" + MODEL_STYLE);
        }
    }


    //获取二维模组型号
    public static String getCompilerModel() {
        return MODEL_STYLE;
    }


    public static byte[] hexToBytes(String hexString) {

        char[] hex = hexString.toCharArray();
        //转rawData长度减半
        int length = hex.length / 2;
        byte[] rawData = new byte[length];
        for (int i = 0; i < length; i++) {
            //先将hex数据转10进制数值
            int high = Character.digit(hex[i * 2], 16);
            int low = Character.digit(hex[i * 2 + 1], 16);
            //将第一个值的二进制值左平移4位,ex: 00001000 => 10000000 (8=>128)
            //然后与第二个值的二进制值作联集ex: 10000000 | 00001100 => 10001100 (137)
            int value = (high << 4) | low;
            //与FFFFFFFF作补集
            if (value > 127)
                value -= 256;
            //最后转回byte就OK
            rawData[i] = (byte) value;
        }
        return rawData;
    }

    //设置4710,4750扫码枪码制  Set the code scanning gun code system for 4750 ,4710
    public void setCodeParameter(Integer[] command) {

        ArrayList list_Coomand = new ArrayList(Arrays.asList(command));
        EventBus.getDefault().post(SdkMessage.getInstance(null, SdkValue.SdkMessageType_Send, ScannerUtil.changeCodeFor4710(list_Coomand)));

    }

    @Override
    public void sendCommand(String command) {
        boolean support = true;
        if (Scanner_type.equals("c")) {
            switch (command) {
                case SdkValue.HIGH_SOUND:
                    command = "$BUZZ#1";
                    break;
                case SdkValue.MIDDLE_SOUND:
                    command = "$BUZZ#2";
                    break;
                case SdkValue.LOW_SOUND:
                    command = "$BUZZ#3";
                    break;
                case SdkValue.OFF_SOUND:
                    command = "$BUZZ#0";
                    break;
                case SdkValue.Sleeptime_A:
                    support = false;
                    break;
                case SdkValue.Sleeptime_B:
                    command = "$RF#ST02";
                    break;
                case SdkValue.Sleeptime_C:
                    command = "$RF#ST06";
                    break;
                case SdkValue.Sleeptime_D:
                    command = "$RF#ST10";
                    break;
                case SdkValue.Sleeptime_E:
                    command = "$RF#ST20";
                    break;
                case SdkValue.Sleeptime_F:
                    command = "$RF#ST60";
                    break;
                case SdkValue.Sleeptime_G:
                    command = "$RF#ST<0";
                    break;
                case SdkValue.Sleeptime_H:
                    command = "$RF#STH0";
                    break;
                case SdkValue.Sleeptime_I:
                    command = "$RF#ST00";
                    break;
            }
        }

        if (support == true) {
            if (isRedy()) {

                EventBus.getDefault().post(SdkMessage.getInstance(null, SdkValue.SdkMessageType_Send, ScannerUtil.getCommandBtye(command)));
            } else {
                Toast.makeText(main_context, "未连接蓝牙或usb", Toast.LENGTH_LONG).show();
            }
        } else {
            Toast.makeText(main_context, "This function is not supported for the " + Scanner_type + " series code sweeping gun", Toast.LENGTH_LONG).show();
        }
    }


    public boolean isRedy() {
        if (connected || usbService != null) {
            return true;
        } else {
            return false;
        }
    }

    /*
     * This handler will be passed to UsbService. Data received from serial port is displayed through this handler
     * cdc usb 的回调
     */
    private static class MyHandler extends Handler {

        public MyHandler() {

        }

        @Override
        public void handleMessage(Message msg) {
            switch (msg.what) {
                case UsbService.MESSAGE_FROM_SERIAL_PORT:
                    Log.d("tag", Arrays.toString((byte[]) msg.obj));
                    EventBus.getDefault().post(SdkMessage.getInstance(null, SdkValue.SdkMessageType_Receve, (byte[]) msg.obj));
                    break;
                case UsbService.CTS_CHANGE:
                    Toast.makeText(main_context, "CTS_CHANGE", Toast.LENGTH_LONG).show();
                    break;
                case UsbService.DSR_CHANGE:
                    Toast.makeText(main_context, "DSR_CHANGE", Toast.LENGTH_LONG).show();
                    break;
            }
        }
    }
}
